package com.hedl.practice.diyJava.encryptionandsecurity.key_exchange_algorithm;

import com.hedl.practice.diyJava.encryptionandsecurity.key_exchange_algorithm.tmp.Person;


/**
 * 我们来看DH算法交换密钥的步骤。假设甲乙双方需要传递密钥，他们之间可以这么做：
 *      甲首选选择一个素数p，例如97，底数g是p的一个原根，例如5，随机数a，例如123，然后计算A=g^a mod p，结果是34，然后，甲发送p＝97，g=5，A=34给乙；
 *      乙方收到后，也选择一个随机数b，例如，456，然后计算B = g^b mod p，结果是75，乙再同时计算s = A^b mod p，结果是22；
 *      乙把计算的B=75发给甲，甲计算s ＝ B^a mod p，计算结果与乙算出的结果一样，都是22。
 *
 * 最终双方协商出的密钥s是22。注意到这个密钥s并没有在网络上传输。
 * 而通过网络传输的p，g，A和B是无法推算出s的，因为实际算法选择的素数是非常大的。
 *
 * 如果我们把a看成甲的私钥，A看成甲的公钥，b看成乙的私钥，B看成乙的公钥，
 * DH算法的本质就是双方各自生成自己的私钥和公钥，私钥仅对自己可见，然后交换公钥，并根据自己的私钥和对方的公钥，生成最终的密钥secretKey，
 * DH算法通过数学定律保证了双方各自计算出的secretKey是相同的
 *
 * 小结：
 *      DH算法是一种密钥交换协议，通信双方通过不安全的信道协商密钥，然后进行对称加密传输。
 *      DH算法没有解决中间人攻击。
 */
public class Client {
    //Bob和Alice
    static Person bob = new Person("Bob");
    static Person alice = new Person("Alice");
    public static void main(String[] args) {
        //各自生成KeyPair
        bob.generateKeyPair();
        alice.generateKeyPair();

        //双方交换各自的PublicKey
        //Bob根据Alice的PublicKey生成自己的本地密钥
        bob.generateSecretKey(alice.getPublicKey().getEncoded());
        // Alice根据Bob的PublicKey生成自己的本地密钥:
        alice.generateSecretKey(bob.getPublicKey().getEncoded());

        //检查双方的本地密钥是否相同:
        bob.printKeys();
        alice.printKeys();
        //双方的SecretKey相同，后续通信将使用SecretKey作为密钥进行AES加解密...
    }
}
